package br.edu.ifrn.potigol.lang;

import br.edu.ifrn.potigol.lang.PotigolClass;
import br.edu.ifrn.potigol.lang.PotigolObject;
import br.edu.ifrn.potigol.lang.TypeError;

/**
 * Armazena um valor Java, normalmente um literal (String, Integer, Float, nil, true, false).
 */
public class ValueObject extends PotigolObject {
  private Object value;
  
  public ValueObject(PotigolClass klass, Object value) {
    super(klass);
    this.value = value;
  }

  public ValueObject(String value) {
    super("String");
    this.value = value;
  }

  public ValueObject(Integer value) {
    super("Integer");
    this.value = value;
  }

  public ValueObject(Float value) {
    super("Float");
    this.value = value;
  }

  public ValueObject(Object value) {
    super("Object");
    this.value = value;
  }
  
  public ValueObject(PotigolObject[] value) {
	 super("Object");
	 this.value = value.length;
  }
  
  /**
   * Retorna o valor Java deste objeto.
   */
  @Override
  public Object toJavaObject() {
    return value;
  }
  
  /**
   * Apenas nulo e falso são falsos.
   */
  @Override
  public boolean isFalse() {
    return value == (Object)false || isNil();
  }
  
  /**
   * Apenas nulo é nulo.
   */
  @Override
  public boolean isNil() {
    return value == null;
  }
  
  public Object getValue() {
    return value;
  }
  
  /**
   * Converte o valor para o mesmo passado como parâmetro ou emite um TypeError se foi passado um tipo inesperado.
   */
  public <T> T getValueAs(Class<T> clazz) throws TypeError {
    if (clazz.isInstance(value)){
      return clazz.cast(value);
    }
    throw new TypeError(clazz.getName(), value);
  }
}
